extends Area2D

signal action_finished
signal character_die(node)

const HURT_LABEL = preload("res://scenes/hurt_label.tscn")

var texture_path:String
var raw_num:int = 8 # 几行
var column_num:int = 4 # 几列
var animate_speed:float = 8 #帧率

var animate_sprite:AnimatedSprite2D = AnimatedSprite2D.new()
var animate_names:Array[String] = ['move','idle','idle-back','hurt','attack','attack-back','die','win']

var original_pos:Vector2 = Vector2.ZERO
var attributes
var group
var cur_hp:
	set(value):
		cur_hp = value
		%hp.value = value
	get:
		return cur_hp
var max_hp:
	set(value):
		%hp.max_value = value
	get:
		return max_hp
const SPEED:float = 800
var is_moving = false
var is_goback = false
var target
var target_pos:Vector2 = Vector2.ZERO

func init(attr):
	attributes = attr
	init_aminates()
	init_status()
	
# 初始化角色的动画
func init_aminates():
	# 计算每帧动画的高宽
	var texture = load("res://assets/character/"+texture_path)
	var frame_width = texture.get_width() / column_num
	var frame_height = texture.get_height() / raw_num
	var sprite_frames = SpriteFrames.new()
	for i in raw_num:
		var animate_name = animate_names[i]
		sprite_frames.add_animation(animate_name)
		for j in column_num:
			var atlas_texture = AtlasTexture.new()
			var rect = Rect2(j*frame_width,i*frame_height,frame_width,frame_height)
			atlas_texture.atlas = texture
			atlas_texture.region = rect
			sprite_frames.add_frame(animate_name,atlas_texture)
			sprite_frames.set_animation_speed(animate_names[i],animate_speed)
			if(not animate_name in ['move','idle','run','win']):
				sprite_frames.set_animation_loop(animate_name,false)
			pass
	animate_sprite.sprite_frames = sprite_frames
	add_child(animate_sprite)
	animate_sprite.play("idle")

#显示血条、名称
func init_status():
	var _name = attributes.name
	%name.text = _name
	max_hp = attributes.attributes.max_hp
	cur_hp = attributes.attributes.max_hp
	pass

func start_attack(_target):
	if attributes.attributes.range_type == "Ranged":
		attack(_target)
	else:
		original_pos = global_position
		is_moving = true
		target = _target
		target_pos = target.global_position

func attack(body):
	animate_sprite.play("attack")
	body.hurt(self)
	animate_sprite.animation_finished.connect(attack_finished)

func attack_finished():
	if attributes.attributes.range_type == "Ranged":
		finished()
		return
	if animate_sprite.flip_h:
		animate_sprite.flip_h = false
	else:
		animate_sprite.flip_h = true
	target_pos = original_pos
	is_moving = true
	is_goback = true

func finished():
	print("finished")
	if attributes.attributes.range_type != "Ranged":
		if animate_sprite.flip_h:
			animate_sprite.flip_h = false
		else:
			animate_sprite.flip_h = true
		is_moving = false
		is_goback = false
	animate_sprite.play("idle")
	action_finished.emit()

func hurt(from):
	var att = from.attributes.attributes.physical_damage if from.attributes.attributes.range_type == "Melee" else from.attributes.attributes.magical_damage
	var defense = attributes.attributes.physical_defense if from.attributes.attributes.range_type == "Melee" else attributes.attributes.magical_defense
	var res = (att - defense)if att > defense else 0
	cur_hp = cur_hp - res
	var hurt_label = HURT_LABEL.instantiate()
	add_child(hurt_label)
	hurt_label.position = $Marker2D.position
	hurt_label.show_text(res)
	animate_sprite.play("hurt")
	await get_tree().create_timer(0.2).timeout
	animate_sprite.play("idle")
	if cur_hp <= 0:
		die()
		
func die():
	animate_sprite.play('die')
	emit_signal("character_die",self)

func _process(delta: float) -> void:
	if is_moving:
		global_position += global_position.direction_to(target_pos) * SPEED * delta
	if is_goback and global_position.distance_to(original_pos) < 20:
		finished()

func _on_area_entered(area: Area2D) -> void:
	if is_moving:
		if(area == target):
			is_moving = false
			attack(area)
